{% extends 'knowledge/base.html' %}
{% load static %}
{% block title %}AI搜索知识库{% endblock %}

{% block extra_css %}
<link rel="stylesheet" href="{% static 'knowledge/css/atom-one-dark.min.css' %}">
<style>
    .search-container {
        transition: all 0.3s ease;
        box-shadow: 0 4px 20px rgba(0, 0, 0, 0.05);
    }
    .search-container:focus-within {
        box-shadow: 0 8px 30px rgba(0, 0, 0, 0.1);
    }
    .settings-panel {
        max-height: 0;
        overflow: hidden;
        transition: max-height 0.4s cubic-bezier(0.4, 0, 0.2, 1), 
                    opacity 0.3s ease, 
                    transform 0.3s ease;
        opacity: 0;
        transform: translateY(-10px);
    }
    .settings-panel.active {
        max-height: 200px;
        opacity: 1;
        transform: translateY(0);
    }
    .answer-container {
        min-height: 150px;
        transition: all 0.3s ease;
    }
    .answer-container:hover {
        box-shadow: 0 8px 30px rgba(0, 0, 0, 0.08);
    }
    .result-item {
        transition: transform 0.2s, box-shadow 0.2s;
        border-left: 3px solid transparent;
    }
    .result-item:hover {
        transform: translateY(-2px);
        box-shadow: 0 6px 24px rgba(0, 0, 0, 0.1);
        border-left-color: var(--color-primary, #165DFF);
    }
    .loading-indicator::after {
        content: '';
        display: inline-block;
        width: 1em;
        height: 1em;
        border: 2px solid rgba(22, 93, 255, 0.3);
        border-radius: 50%;
        border-top-color: #165DFF;
        animation: spin 1s ease-in-out infinite;
    }
    @keyframes spin {
        to { transform: rotate(360deg); }
    }
    .line-clamp-3 {
        display: -webkit-box;
        -webkit-line-clamp: 3;
        -webkit-box-orient: vertical;
        overflow: hidden;
    }
    .search-input-wrapper {
        position: relative;
        flex: 1;
    }
    .search-input-wrapper i {
        position: absolute;
        left: 16px;
        top: 50%;
        transform: translateY(-50%);
        color: #a0aec0;
        transition: color 0.2s;
    }
    .search-input-wrapper input:focus + i {
        color: var(--color-primary, #165DFF);
    }
    .search-input {
        width: 100%;
        padding-left: 40px;
        padding-right: 16px;
        height: 50px;
        border-radius: 10px;
        border: 1px solid #e2e8f0;
        transition: all 0.2s;
        font-size: 1rem;
    }
    .search-input:focus {
        outline: none;
        border-color: var(--color-primary, #165DFF);
        box-shadow: 0 0 0 3px rgba(22, 93, 255, 0.15);
    }
    .fade-in {
        animation: fadeIn 0.5s ease forwards;
    }
    @keyframes fadeIn {
        from { opacity: 0; transform: translateY(10px); }
        to { opacity: 1; transform: translateY(0); }
    }
    .prose pre {
        background-color: #f8fafc;
        border-radius: 6px;
        padding: 1rem;
        overflow-x: auto;
    }
    .prose code {
        background-color: #f1f5f9;
        padding: 0.2em 0.4em;
        border-radius: 3px;
        font-size: 0.9em;
    }
    .prose h1, .prose h2, .prose h3, .prose h4 {
        margin-top: 1.5em;
        margin-bottom: 0.75em;
    }
    .prose p {
        margin-bottom: 1em;
    }
    .prose ul, .prose ol {
        padding-left: 1.5em;
        margin-bottom: 1em;
    }
</style>
{% endblock %}

{% block content %}
<div class="max-w-5xl mx-auto">
    <!-- 搜索区域 -->
    <div class="bg-white rounded-xl shadow-sm p-6 mb-8 search-container">
        <form id="search-form" class="flex flex-col md:flex-row gap-4">
            <div class="search-input-wrapper">
                <input type="text" id="query-input" name="q" placeholder="请输入搜索关键词..." value="{{ query }}"
                       class="search-input focus:outline-none focus:ring-2 focus:ring-primary/30 focus:border-primary">
                <i class="fa fa-search"></i>
            </div>
            <div class="w-full md:w-48">
                <select id="collection-select" name="collection"
                        class="w-full px-4 h-[50px] rounded-lg border border-gray-200 focus:outline-none focus:ring-2 focus:ring-primary/30 focus:border-primary bg-white">
                    <option value="">全部集合</option>
                    {% for collection in collections %}
                        <option value="{{ collection }}" {% if collection_name == collection %}selected{% endif %}>{{ collection }}</option>
                    {% endfor %}
                </select>
            </div>
            <div class="flex gap-3">
                <button type="button" id="settings-btn" class="px-4 h-[50px] rounded-lg border border-gray-200 bg-gray-50 hover:bg-gray-100 text-neutral-dark flex items-center justify-center gap-2 transition-all duration-200">
                    <i class="fa fa-cog"></i>
                    <span class="hidden sm:inline">设置</span>
                </button>
                <button type="submit" class="px-6 h-[50px] rounded-lg bg-primary text-white hover:bg-primary/90 flex items-center justify-center gap-2 font-medium transition-all duration-200 shadow-sm hover:shadow">
                    <i class="fa fa-search"></i>
                    <span>搜索</span>
                </button>
            </div>
        </form>

        <!-- 设置面板 -->
        <div id="settings-panel" class="settings-panel mt-4 pt-4 border-t border-gray-100">
            <div class="grid grid-cols-1 md:grid-cols-2 gap-6">
                <div>
                    <label for="n-results" class="block text-sm font-medium text-neutral-dark mb-2">返回结果数量</label>
                    <input type="number" id="n-results" name="n" min="1" max="20" value="{{ n_results|default:5 }}"
                           class="w-full px-4 py-2 rounded-lg border border-gray-200 focus:outline-none focus:ring-2 focus:ring-primary/30 focus:border-primary">
                    <p class="text-xs text-gray-500 mt-1">设置搜索返回的最大结果数量（1-20）</p>
                </div>
                <div>
                    <label for="min-score" class="block text-sm font-medium text-neutral-dark mb-2">相似度阈值 (<span id="min-score-value">{{ min_score|default:0.5 }}</span>)</label>
                    <input type="range" id="min-score" name="min_score" min="0" max="1" step="0.01" value="{{ min_score|default:0.5 }}" 
                           class="w-full h-2 bg-gray-200 rounded-lg appearance-none cursor-pointer accent-primary">
                    <div class="flex justify-between text-xs text-gray-500 mt-1">
                        <span>0.0（包含更多结果）</span>
                        <span>1.0（仅精确匹配）</span>
                    </div>
                </div>
            </div>
        </div>
    </div>

    <!-- AI回答区域 -->
    {% if query %}
    <div class="bg-white rounded-xl shadow-sm p-6 mb-8 answer-container">
        <div class="flex items-center justify-between mb-4">
            <h2 class="text-lg font-semibold text-gray-800 flex items-center gap-2">
                <i class="fa fa-robot text-primary"></i>
                <span>AI回答</span>
            </h2>
            <div id="answer-status" class="text-sm text-neutral hidden">
                <span class="loading-indicator mr-2"></span>正在生成回答...
            </div>
        </div>
        <div id="answer-content" class="prose max-w-none text-gray-700 leading-relaxed min-h-[120px] p-2">
            {% if answer %}
                {{ answer|linebreaks }}
            {% else %}
                <div class="text-center text-neutral py-10 fade-in">
                    <i class="fa fa-comment-o text-4xl mb-3 opacity-30"></i>
                    <p class="text-lg">搜索后将显示AI回答结果</p>
                    <p class="text-sm text-gray-500 mt-2">基于知识库内容生成的智能回答</p>
                </div>
            {% endif %}
        </div>
    </div>
    {% endif %}

    <!-- 知识库结果区域 -->
    {% if query %}
    <div class="bg-white rounded-xl shadow-sm overflow-hidden">
        <div class="p-6 border-b border-gray-100">
            <h2 class="text-lg font-semibold text-gray-800 flex items-center gap-2">
                <i class="fa fa-database text-secondary"></i>
                <span>知识库结果</span>
                <span class="text-sm font-normal text-neutral ml-2 results-count">({{ results|length }} 条结果)</span>
            </h2>
        </div>
        <div class="divide-y divide-gray-100">
            {% if results %}
                {% for result in results %}
                <div class="p-6 result-item">
                    <div class="flex justify-between items-start mb-3">
                        <h3 class="font-medium text-gray-800 flex items-center">
                            <i class="fa fa-file-text-o mr-2 text-secondary"></i>
                            文档 {{ result.document_id }}
                        </h3>
                        <span class="px-3 py-1 bg-primary/10 text-primary text-xs rounded-full font-medium">
                            相似度: {{ result.score|floatformat:2 }}
                        </span>
                    </div>
                    {% if result.metadata.collection %}
                    <div class="text-xs text-neutral mb-3 flex items-center">
                        <i class="fa fa-folder-o mr-1"></i> 
                        <span>集合: </span>
                        <span class="ml-1 px-2 py-0.5 bg-gray-100 rounded-md">{{ result.metadata.collection }}</span>
                    </div>
                    {% endif %}
                    <div class="text-gray-700 text-sm leading-relaxed bg-gray-50 p-4 rounded-lg {% if result.text|length > 300 %}line-clamp-3{% endif %}">
                        {{ result.text|linebreaks }}
                    </div>
                    {% if result.text|length > 300 %}
                    <button class="mt-3 text-primary text-sm hover:text-primary/80 flex items-center gap-1 transition-all duration-200"
                            onclick="this.previousElementSibling.classList.toggle('line-clamp-3');
                                     const icon = this.querySelector('i');
                                     if (this.previousElementSibling.classList.contains('line-clamp-3')) {
                                         this.querySelector('span').textContent = '显示更多';
                                         icon.className = 'fa fa-chevron-down text-xs';
                                     } else {
                                         this.querySelector('span').textContent = '收起';
                                         icon.className = 'fa fa-chevron-up text-xs';
                                     }">
                        <span>显示更多</span>
                        <i class="fa fa-chevron-down text-xs"></i>
                    </button>
                    {% endif %}
                </div>
                {% endfor %}
            {% else %}
                <div class="p-12 text-center text-neutral fade-in">
                    <i class="fa fa-search text-5xl mb-4 opacity-30"></i>
                    <p class="text-lg">未找到相关知识库内容</p>
                    <p class="text-sm text-gray-500 mt-2">尝试使用不同的关键词或降低相似度阈值</p>
                </div>
            {% endif %}
        </div>
    </div>
    {% endif %}
</div>
{% endblock %}

{% block extra_js %}
<script src="{% static 'knowledge/js/marked.umd.min.js' %}"></script>
<script src="{% static 'knowledge/js/highlight.min.js' %}"></script>
<script>
    document.addEventListener('DOMContentLoaded', function() {
        // 设置面板切换
        const settingsBtn = document.getElementById('settings-btn');
        const settingsPanel = document.getElementById('settings-panel');
        const minScoreInput = document.getElementById('min-score');
        const minScoreValue = document.getElementById('min-score-value');

        settingsBtn.addEventListener('click', function() {
            settingsPanel.classList.toggle('active');
            // 添加按钮激活状态
            this.classList.toggle('bg-gray-100');
            this.classList.toggle('border-primary');
        });

        // 更新相似度阈值显示
        minScoreInput.addEventListener('input', function() {
            minScoreValue.textContent = this.value;
        });

        // 搜索表单提交处理
        const searchForm = document.getElementById('search-form');
        const queryInput = document.getElementById('query-input');
        let answerContent = document.getElementById('answer-content');
        let answerStatus = document.getElementById('answer-status');
        
        // 如果元素不存在，创建它们
        if (!answerContent || !answerStatus) {
            // 创建AI回答容器
            const answerContainer = document.createElement('div');
            answerContainer.className = 'bg-white rounded-xl shadow-sm p-6 mb-8 answer-container';
            
            const headerDiv = document.createElement('div');
            headerDiv.className = 'flex items-center justify-between mb-4';
            headerDiv.innerHTML = `
                <h2 class="text-lg font-semibold text-gray-800 flex items-center gap-2">
                    <i class="fa fa-robot text-primary"></i>
                    <span>AI回答</span>
                </h2>
                <div id="answer-status" class="text-sm text-neutral hidden">
                    <span class="loading-indicator mr-2"></span>正在生成回答...
                </div>
            `;
            
            const contentDiv = document.createElement('div');
            contentDiv.id = 'answer-content';
            contentDiv.className = 'prose max-w-none text-gray-700 leading-relaxed min-h-[120px] p-2';
            
            answerContainer.appendChild(headerDiv);
            answerContainer.appendChild(contentDiv);
            
            // 插入到搜索容器之后
            const searchContainer = document.querySelector('.search-container');
            searchContainer.insertAdjacentElement('afterend', answerContainer);
            
            // 更新引用
            answerContent = contentDiv;
            answerStatus = document.getElementById('answer-status');
        }

        searchForm.addEventListener('submit', async function(e) {
            e.preventDefault();
            const query = queryInput.value.trim();
            if (!query) return;

            const collection = document.getElementById('collection-select').value;
            const nResults = document.getElementById('n-results').value;
            const minScore = document.getElementById('min-score').value;

            // 确保结果容器可见
            const answerContainer = answerContent.closest('.answer-container');
            if (answerContainer) {
                answerContainer.style.display = 'block';
            }

            // 清空之前的结果并显示加载动画
            answerContent.innerHTML = `
                <div class="text-center text-neutral py-10 fade-in">
                    <i class="fa fa-circle-o-notch fa-spin text-4xl mb-3 text-primary opacity-70"></i>
                    <p class="text-lg">正在搜索知识库...</p>
                    <p class="text-sm text-gray-500 mt-2">请稍候，正在处理您的请求</p>
                </div>
            `;

            try {
                // 创建或确保知识库结果容器存在
                let resultsContainer = document.querySelector('.bg-white.rounded-xl.shadow-sm.overflow-hidden');
                if (!resultsContainer) {
                    resultsContainer = document.createElement('div');
                    resultsContainer.className = 'bg-white rounded-xl shadow-sm overflow-hidden';
                    
                    const headerDiv = document.createElement('div');
                    headerDiv.className = 'p-6 border-b border-gray-100';
                    headerDiv.innerHTML = `
                        <h2 class="text-lg font-semibold text-gray-800 flex items-center gap-2">
                            <i class="fa fa-database text-secondary"></i>
                            <span>知识库结果</span>
                            <span class="text-sm font-normal text-neutral ml-2 results-count">(0 条结果)</span>
                        </h2>
                    `;
                    
                    const contentDiv = document.createElement('div');
                    contentDiv.className = 'divide-y divide-gray-100';
                    
                    resultsContainer.appendChild(headerDiv);
                    resultsContainer.appendChild(contentDiv);
                    
                    // 插入到页面中
                    const container = document.querySelector('.max-w-5xl.mx-auto');
                    container.appendChild(resultsContainer);
                }

                // 第一步：获取知识库搜索结果
                const kbUrl = new URL('/ai-search/', window.location.origin);
                kbUrl.searchParams.set('q', query);
                kbUrl.searchParams.set('type', 'kb_only');
                kbUrl.searchParams.set('n', nResults);
                kbUrl.searchParams.set('min_score', minScore);
                kbUrl.searchParams.set('ajax', 'true');
                if (collection) kbUrl.searchParams.set('collection_name', collection);

                console.log('知识库搜索URL:', kbUrl.toString());

                const kbResponse = await fetch(kbUrl, { 
                    headers: { 'X-Requested-With': 'XMLHttpRequest' },
                    credentials: 'same-origin'
                });
                
                if (!kbResponse.ok) {
                    throw new Error(`HTTP错误! 状态码: ${kbResponse.status}`);
                }
                
                const kbData = await kbResponse.json();
                console.log('知识库搜索结果:', kbData);

                // 更新知识库结果区域
                updateKnowledgeResults(kbData.results || []);

                // 第二步：如果有知识库结果，获取AI回答
                if (kbData.results && kbData.results.length > 0) {
                    // 准备AI回答区域
                    if (answerStatus) {
                        answerStatus.classList.remove('hidden');
                        answerStatus.innerHTML = '<span class="loading-indicator mr-2"></span>正在生成回答...';
                    }
                    
                    marked.setOptions({
  highlight: function(code, lang) {
    const language = hljs.getLanguage(lang) ? lang : 'plaintext';
    return hljs.highlight(code, { language }).value;
  },
  breaks: true,
  gfm: true
});
answerContent.innerHTML = marked.parse('');
answerContent.classList.add('p-4', 'bg-gray-50', 'rounded-lg');

                    // 构建AI请求URL
                    const aiUrl = new URL('/ai-search/', window.location.origin);
                    aiUrl.searchParams.set('q', query);
                    aiUrl.searchParams.set('type', 'ai_only');
                    aiUrl.searchParams.set('n', nResults);
                    aiUrl.searchParams.set('min_score', minScore);
                    aiUrl.searchParams.set('ajax', 'true');
                    if (collection) aiUrl.searchParams.set('collection_name', collection);

                    console.log('AI回答URL:', aiUrl.toString());
                    
                    try {
                        // 使用Fetch API处理流式响应
                        const aiResponse = await fetch(aiUrl, {
                            headers: { 'X-Requested-With': 'XMLHttpRequest' },
                            credentials: 'same-origin'
                        });
                        
                        if (!aiResponse.ok) {
                            // 尝试解析错误响应为JSON
                            let errorData;
                            try {
                                errorData = await aiResponse.json();
                            } catch (e) {
                                // 如果解析失败，使用状态文本
                                throw new Error(errorData?.error || `AI响应错误! 状态码: ${aiResponse.status}`);
                            }
                            throw new Error(errorData?.error || `AI响应错误! 状态码: ${aiResponse.status}`);
                        }
                        
                        // 获取响应流
                        const reader = aiResponse.body.getReader();
                        const decoder = new TextDecoder();
                        let accumulatedContent = '';
                        
                        // 处理流数据
                        while (true) {
                            const { done, value } = await reader.read();
                            if (done) {
                                // 流结束，表示完成
                                break;
                            }
                            
                            // 直接解码文本内容并添加到页面
                            const textChunk = decoder.decode(value, { stream: true });
                            if (textChunk) {
                                accumulatedContent += textChunk;
                                answerContent.innerHTML = marked.parse(accumulatedContent);
                                // 滚动到底部
                                answerContent.scrollTop = answerContent.scrollHeight;
                            }
                        }
                        
                        // 完成后隐藏加载状态并添加完成动画
                        if (answerStatus) {
                            answerStatus.classList.add('hidden');
                        }
                        answerContent.classList.add('fade-in');
                        
                    } catch (error) {
                        console.error('获取AI回答时出错:', error);
                        if (answerStatus) {
                            answerStatus.classList.add('hidden');
                        }
                        answerContent.innerHTML = `<div class="text-center text-red-500 py-10">
                            <i class="fa fa-exclamation-triangle text-4xl mb-3"></i>
                            <p class="text-lg">获取AI回答时出错</p>
                            <p class="text-sm text-gray-500 mt-2">${error.message || '请稍后再试'}</p>
                        </div>`;
                    }
                } else {
                    if (answerStatus) {
                        answerStatus.classList.add('hidden');
                    }
                    answerContent.innerHTML = `
                        <div class="text-center text-neutral py-10 fade-in">
                            <i class="fa fa-exclamation-circle text-4xl mb-3 opacity-50 text-amber-500"></i>
                            <p class="text-lg">未找到相关知识库内容</p>
                            <p class="text-sm text-gray-500 mt-2">尝试使用不同的关键词或降低相似度阈值</p>
                        </div>
                    `;
                }
            } catch (error) {
                console.error('搜索过程中发生错误:', error);
                
                if (answerStatus) {
                    answerStatus.classList.add('hidden');
                }
                
                answerContent.innerHTML = `
                    <div class="text-center text-red-500 py-10 fade-in">
                        <i class="fa fa-exclamation-triangle text-4xl mb-3"></i>
                        <p class="text-lg">搜索出错</p>
                        <p class="text-sm mt-2">${error.message || '未知错误'}</p>
                        <button class="mt-4 px-4 py-2 bg-gray-100 hover:bg-gray-200 text-gray-700 rounded-lg transition-all duration-200"
                                onclick="location.reload()">
                            <i class="fa fa-refresh mr-2"></i>刷新页面
                        </button>
                    </div>
                `;
                
                // 确保知识库结果区域显示错误状态
                updateKnowledgeResults([]);
            }
        });

        // 更新知识库结果显示
        function updateKnowledgeResults(results) {
            // 确保结果容器存在
            let resultsContainer = document.querySelector('.divide-y');
            if (!resultsContainer) {
                // 如果不存在，创建知识库结果容器
                const mainContainer = document.createElement('div');
                mainContainer.className = 'bg-white rounded-xl shadow-sm overflow-hidden';
                
                const headerDiv = document.createElement('div');
                headerDiv.className = 'p-6 border-b border-gray-100';
                headerDiv.innerHTML = `
                    <h2 class="text-lg font-semibold text-gray-800 flex items-center gap-2">
                        <i class="fa fa-database text-secondary"></i>
                        <span>知识库结果</span>
                        <span class="text-sm font-normal text-neutral ml-2 results-count">(0 条结果)</span>
                    </h2>
                `;
                
                resultsContainer = document.createElement('div');
                resultsContainer.className = 'divide-y divide-gray-100';
                
                mainContainer.appendChild(headerDiv);
                mainContainer.appendChild(resultsContainer);
                
                // 插入到页面中
                const container = document.querySelector('.max-w-5xl.mx-auto');
                if (container) {
                    container.appendChild(mainContainer);
                } else {
                    console.error('找不到主容器，无法添加知识库结果区域');
                    return;
                }
            }

            // 更新结果计数
            const resultCountEl = document.querySelector('.results-count');
            if (resultCountEl) {
                resultCountEl.textContent = `(${results && results.length || 0} 条结果)`;
            }

            try {
                if (results && results.length > 0) {
                    let html = '';
                    results.forEach(result => {
                        // 安全处理可能的undefined值
                        const documentId = result.document_id || '未知';
                        const score = typeof result.score === 'number' ? result.score.toFixed(2) : '0.00';
                        const text = result.text || '无内容';
                        const collection = result.collection || (result.metadata && result.metadata.collection);
                        const truncated = text.length > 300;
                        
                        html += `
                        <div class="p-6 result-item fade-in">
                            <div class="flex justify-between items-start mb-3">
                                <h3 class="font-medium text-gray-800 flex items-center">
                                    <i class="fa fa-file-text-o mr-2 text-secondary"></i>
                                    文档 ${documentId}
                                </h3>
                                <span class="px-3 py-1 bg-primary/10 text-primary text-xs rounded-full font-medium">
                                    相似度: ${score}
                                </span>
                            </div>
                            ${collection ? `
                            <div class="text-xs text-neutral mb-3 flex items-center">
                                <i class="fa fa-folder-o mr-1"></i> 
                                <span>集合: </span>
                                <span class="ml-1 px-2 py-0.5 bg-gray-100 rounded-md">${collection}</span>
                            </div>` : ''}
                            <div class="text-gray-700 text-sm leading-relaxed bg-gray-50 p-4 rounded-lg ${truncated ? 'line-clamp-3' : ''}">
                                ${text.replace(/\n/g, '<br>')}
                            </div>
                            ${truncated ? `
                            <button class="mt-3 text-primary text-sm hover:text-primary/80 flex items-center gap-1 transition-all duration-200"
                                    onclick="this.previousElementSibling.classList.toggle('line-clamp-3');
                                             const icon = this.querySelector('i');
                                             if (this.previousElementSibling.classList.contains('line-clamp-3')) {
                                                 this.querySelector('span').textContent = '显示更多';
                                                 icon.className = 'fa fa-chevron-down text-xs';
                                             } else {
                                                 this.querySelector('span').textContent = '收起';
                                                 icon.className = 'fa fa-chevron-up text-xs';
                                             }">
                                <span>显示更多</span>
                                <i class="fa fa-chevron-down text-xs"></i>
                            </button>` : ''}
                        </div>
                        `;
                    });
                    resultsContainer.innerHTML = html;
                } else {
                    resultsContainer.innerHTML = `
                    <div class="p-12 text-center text-neutral fade-in">
                        <i class="fa fa-search text-5xl mb-4 opacity-30"></i>
                        <p class="text-lg">未找到相关知识库内容</p>
                        <p class="text-sm text-gray-500 mt-2">尝试使用不同的关键词或降低相似度阈值</p>
                    </div>
                    `;
                }
            } catch (error) {
                console.error('更新知识库结果时出错:', error);
                resultsContainer.innerHTML = `
                <div class="p-12 text-center text-red-500 fade-in">
                    <i class="fa fa-exclamation-circle text-4xl mb-3"></i>
                    <p class="text-lg">处理结果时出错</p>
                    <p class="text-sm mt-2">${error.message || '未知错误'}</p>
                </div>
                `;
            }
        }
    });
</script>
{% endblock %}